package com.example.demorabbitmq1.rabbit.order.cancel.queue;


import com.example.demorabbitmq1.config.RabbitForOrderCancelConfig;
import com.example.demorabbitmq1.model.MsgForOrderCancel;
import com.google.gson.Gson;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;

@Component
@RabbitListener(queues = {RabbitForOrderCancelConfig.PROCESS_QUEUE_FOR_ORDERCANCEL})
public class DelayForOrderCancelReceiver {
    @RabbitHandler
    public void process(String msgStr, Channel channel, Message message) throws Exception {

        Gson gson=new Gson();
        MsgForOrderCancel msgForOrderCancel = gson.fromJson(msgStr, MsgForOrderCancel.class);//把对象转为JSON格式的字符串

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("当前时间: " + sdf.format(new Date()) + " ---> msg：【  " + msgForOrderCancel.getContent() + "]");

//        try {
//            //告诉服务器收到这条消息 已经被我消费了 可以在队列删掉 这样以后就不会再发了 否则消息服务器以为这条消息没处理掉 后续还会在发
//            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
//            System.out.println("receiver success");
//        } catch (IOException e) {
//            e.printStackTrace();
//            //丢弃这条消息
//            //channel.basicNack(message.getMessageProperties().getDeliveryTag(), false,false);
//            System.out.println("receiver fail");
//        }

        try {
            System.out.println(
                    "消费端接收到消息:" + message.getMessageProperties() + ":" + new String(message.getBody()));
            System.out.println("topic:" + message.getMessageProperties().getReceivedRoutingKey());
            // deliveryTag是消息传送的次数，我这里是为了让消息队列的第一个消息到达的时候抛出异常，处理异常让消息重新回到队列，然后再次抛出异常，处理异常拒绝让消息重回队列
					/*if (message.getMessageProperties().getDeliveryTag() == 1
							|| message.getMessageProperties().getDeliveryTag() == 2) {
						throw new Exception();
					}*/

            //Integer aa = Integer.valueOf(null);//用于 故意模拟 出错

            //给三次机会,如果
            if (message.getMessageProperties().getDeliveryTag() >= 3) {
                System.out.println("给三次机会 ...  直接先确认数据,并存储 db 记录下来 脏数据,待人工干预 处理");

                //TODO 存储 db 记录下来
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); // false只确认当前一个消息收到，true确认所有consumer获得的消息

            }


            //这里做业务 操作


            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); // false只确认当前一个消息收到，true确认所有consumer获得的消息
        } catch (Exception e) {
            e.printStackTrace();

            //给三次机会,如果
            if (message.getMessageProperties().getDeliveryTag() == 3) {
                System.out.println("给三次机会 ...  直接先确认数据,并存储 db 记录下来 脏数据,待人工干预 处理");

                //TODO 存储 db 记录下来
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); // false只确认当前一个消息收到，true确认所有consumer获得的消息


            }else{
                if (message.getMessageProperties().getRedelivered()) {
                    System.out.println("消息已重复处理失败,拒绝再次接收...");
                    channel.basicReject(message.getMessageProperties().getDeliveryTag(), true); // 拒绝消息
                } else {
                    System.out.println("消息即将再次返回队列处理...");
                    channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true); // requeue为是否重新回到队列
                }
            }


        }
    }
}
